package co.edu.javeriana.touresbalon.oms.services;

import co.edu.javeriana.touresbalon.b2c.entities.Producto;
import co.edu.javeriana.touresbalon.oms.entities.Orders;
import co.edu.javeriana.touresbalon.oms.enumerations.HotelType;
import co.edu.javeriana.touresbalon.oms.enumerations.OrderProcessState;
import co.edu.javeriana.touresbalon.oms.enumerations.ReprocessingPoint;
import co.edu.javeriana.touresbalon.oms.enumerations.TransportType;
import co.edu.javeriana.touresbalon.oms.utils.Utils;
import co.edu.javeriana.touresbalon.oms.webservices.clients.accounting.AccountingClient;
import co.edu.javeriana.touresbalon.oms.webservices.clients.bpel.WSBPELClient;
import co.edu.javeriana.touresbalon.oms.webservices.clients.creditcard.CreditCardClient;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author ada
 */
@Stateless
public class ReprocesarOrdenBeanService implements ReprocesarOrdenBeanServiceLocal {

    @PersistenceContext(unitName = "TouresBalon_OMS-ejbPU")
    EntityManager manager;
    @EJB
    EspectaculosBeanServiceLocal espectaculosBeanServiceLocal;

    @Override
    public ReprocessingPoint reprocesarOrden(String idOrden, ReprocessingPoint reprocesingPoint) {
        //Se busca orden
        Orders orderToReprocess = manager.find(Orders.class, idOrden);
        orderToReprocess.getItemsList().size();
        Integer idProduct = orderToReprocess.getItemsList().get(0).getProductid().intValue();

        //se busca producto
        Producto productoToReprocess = espectaculosBeanServiceLocal.consultarProducto(idProduct);
        productoToReprocess.getIdHotel().setCheckin(Utils.nowXmlGregorianCalendar());
        productoToReprocess.getIdHotel().setCheckout(Utils.nowXmlGregorianCalendar());
        productoToReprocess.getTransporteCollection().get(0).setFechaSalida(Utils.nowXmlGregorianCalendar());
        productoToReprocess.getTransporteCollection().get(0).setFechaLlegada(Utils.nowXmlGregorianCalendar());

        //se reprocesa
        if (orderToReprocess != null) {
            switch (reprocesingPoint) {
                case EN_VALIDACION:
                    if (reprocesarEnValidacion(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.EN_VALIDACION;
                    }
                    break;
                case EN_RESERVACION:
                    if (reprocesarEnReservacion(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.EN_RESERVACION;
                    }
                    break;
                case CERRADA_CARGO_TARJETA:
                    if (reprocesarCargoTarjeta(orderToReprocess)) {
                        return ReprocessingPoint.CERRADA_CARGO_TARJETA;
                    }
                    if (reprocesarCargoOrden(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ORDEN;
                    }
                    if (reprocesarCargoTransporte(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_TRANSPORTE;
                    }
                    if (reprocesarCargoHospedaje(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_HOSPEDAJE;
                    }
                    if (reprocesarCargoEspectaculo(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ESPECTACULO;
                    }
                    break;
                case CERRADA_CONTABILIDAD_CARGO_ORDEN:
                    if (reprocesarCargoOrden(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ORDEN;
                    }
                    if (reprocesarCargoTransporte(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_TRANSPORTE;
                    }
                    if (reprocesarCargoHospedaje(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_HOSPEDAJE;
                    }
                    if (reprocesarCargoEspectaculo(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ESPECTACULO;
                    }
                    break;
                case CERRADA_CONTABILIDAD_CARGO_TRANSPORTE:
                    if (reprocesarCargoTransporte(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_TRANSPORTE;
                    }
                    if (reprocesarCargoHospedaje(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_HOSPEDAJE;
                    }
                    if (reprocesarCargoEspectaculo(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ESPECTACULO;
                    }
                    break;
                case CERRADA_CONTABILIDAD_CARGO_HOSPEDAJE:
                    if (reprocesarCargoHospedaje(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_HOSPEDAJE;
                    }
                    if (reprocesarCargoEspectaculo(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ESPECTACULO;
                    }
                    break;
                case CERRADA_CONTABILIDAD_CARGO_ESPECTACULO:
                    if (reprocesarCargoEspectaculo(orderToReprocess, productoToReprocess)) {
                        return ReprocessingPoint.CERRADA_CONTABILIDAD_CARGO_ESPECTACULO;
                    }
                    break;
            }
            orderToReprocess.setProcessStatus(OrderProcessState.OK.name());
            return ReprocessingPoint.OK_REPROCESSING;
        } else {
            return ReprocessingPoint.UNDEFINED_ORDER;
        }
    }

    private boolean reprocesarEnValidacion(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            //Reprocesamiento de toda la orden NO se hace compesación, se llama servicio de BPEL
            WSBPELClient wSBPELClient = new WSBPELClient();
            wSBPELClient.callOrderProcess(orderToReprocess, productoToReprocess);
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }

    private boolean reprocesarEnReservacion(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            //reprocesamiento de toda la orden SI se hace compesación cancela servicios, se llama servicio de BPEL
            WSBPELClient wSBPELClient = new WSBPELClient();
            wSBPELClient.callOrderProcess(orderToReprocess, productoToReprocess);
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }

    private boolean reprocesarCargoTarjeta(Orders orderToReprocess) {
        try {
            //reprocesamiento ya al final, se llama servicio de cargar tarjeta
            CreditCardClient creditCardClient = new CreditCardClient();
            boolean resultado = creditCardClient.cargarTarjeta(orderToReprocess.getPrice().doubleValue(), orderToReprocess.getCustid().getCreditcardnumber(), orderToReprocess.getCustid().getCreditcardtype());
            return !resultado;
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
    }

    private boolean reprocesarCargoOrden(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            // contabilidad servicio cargar Orden
            AccountingClient accountingClient = new AccountingClient();
            String tipoHotel = productoToReprocess.getIdHotel().getTipoHotel();
            String tipoTransporte = productoToReprocess.getTransporteCollection().get(0).getTipoTransporte();
            int hotelId = 0;
            int transportId = 0;

            if (tipoHotel.equalsIgnoreCase(HotelType.HILTON.name())) {
                hotelId = 2456;
            } else if (tipoHotel.equalsIgnoreCase(HotelType.DC.name())) {
                hotelId = 2349;
            } else {
                hotelId = 2000;
            }

            if (tipoTransporte.equalsIgnoreCase(TransportType.AA.name())) {
                transportId = 1254;
            } else if (tipoTransporte.equalsIgnoreCase(TransportType.AVIANCA.name())) {
                transportId = 1234;
            } else if (tipoTransporte.equalsIgnoreCase(TransportType.BOLIVARIANO.name())) {
                transportId = 1198;
            } else {
                transportId = 1000;
            }
            Date now = new Date();
            Calendar nowCalendar = Calendar.getInstance();
            nowCalendar.setTime(now);
            accountingClient.ingresarOrden(0, Integer.parseInt(orderToReprocess.getOrderid()), nowCalendar.get(Calendar.YEAR), nowCalendar.get(Calendar.MONTH) + 1, nowCalendar.get(Calendar.DAY_OF_MONTH), hotelId + "" + transportId, -1, orderToReprocess.getPrice().intValue());
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }

    private boolean reprocesarCargoTransporte(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            //contabilidad servicio cargar transporte
            AccountingClient accountingClient = new AccountingClient();

            String tipoTransporte = productoToReprocess.getTransporteCollection().get(0).getTipoTransporte();
            int transportId = 0;


            if (tipoTransporte.equalsIgnoreCase(TransportType.AA.name())) {
                transportId = 1254;
            } else if (tipoTransporte.equalsIgnoreCase(TransportType.AVIANCA.name())) {
                transportId = 1234;
            } else if (tipoTransporte.equalsIgnoreCase(TransportType.BOLIVARIANO.name())) {
                transportId = 1198;
            } else {
                transportId = 1000;
            }
            Date now = new Date();
            Calendar nowCalendar = Calendar.getInstance();
            nowCalendar.setTime(now);

            int withdrawalAmount = orderToReprocess.getNumTravelers() * productoToReprocess.getTransporteCollection().get(0).getCostoSilla().intValue();

            accountingClient.ingresarOrden(0, Integer.parseInt(orderToReprocess.getOrderid()), nowCalendar.get(Calendar.YEAR), nowCalendar.get(Calendar.MONTH) + 1, nowCalendar.get(Calendar.DAY_OF_MONTH), transportId + "", withdrawalAmount, -1);
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }

    private boolean reprocesarCargoHospedaje(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            //contabilidad servicio cargar hospedaje            
            AccountingClient accountingClient = new AccountingClient();
            String tipoHotel = productoToReprocess.getIdHotel().getTipoHotel();

            int hotelId = 0;


            if (tipoHotel.equalsIgnoreCase(HotelType.HILTON.name())) {
                hotelId = 2456;
            } else if (tipoHotel.equalsIgnoreCase(HotelType.DC.name())) {
                hotelId = 2349;
            } else {
                hotelId = 2000;
            }

            Date now = new Date();
            Calendar nowCalendar = Calendar.getInstance();
            nowCalendar.setTime(now);

            int withdrawalAmount = orderToReprocess.getNumTravelers() * productoToReprocess.getIdHotel().getHabitacionesList().get(0).getPrecioNoche().intValue();

            accountingClient.ingresarOrden(0, Integer.parseInt(orderToReprocess.getOrderid()), nowCalendar.get(Calendar.YEAR), nowCalendar.get(Calendar.MONTH) + 1, nowCalendar.get(Calendar.DAY_OF_MONTH), hotelId + "", withdrawalAmount, -1);
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }

    private boolean reprocesarCargoEspectaculo(Orders orderToReprocess, Producto productoToReprocess) {
        try {
            //contabilidad servicio cargar espectaculo
            AccountingClient accountingClient = new AccountingClient();
            Date now = new Date();
            Calendar nowCalendar = Calendar.getInstance();
            nowCalendar.setTime(now);

            int withdrawalAmount = orderToReprocess.getNumTravelers() * productoToReprocess.getIdEspectaculo().getValorEspectaculo().intValue();

            accountingClient.ingresarOrden(0, Integer.parseInt(orderToReprocess.getOrderid()), nowCalendar.get(Calendar.YEAR), nowCalendar.get(Calendar.MONTH) + 1, nowCalendar.get(Calendar.DAY_OF_MONTH), "3000", withdrawalAmount, -1);
        } catch (Exception ex) {
            ex.printStackTrace();
            return true;
        }
        return false;
    }
}
